import { canUseDom } from '@/library/tool-kits/can-use-dom'

type ScrollElement = HTMLElement | Window

const defaultRoot = canUseDom ? window : undefined

const overflowStylePatterns = ['scroll', 'auto', 'overlay']

const isElement = (node: Element) => node.nodeType === 1

/**
 * @description 查找距离指定元素最近的“可纵向滚动”的祖先节点。
 *
 * @param el    起始 DOM 节点，从它开始向上遍历。
 * @param root  遍历终止边界。一旦遇到该节点就停止查找，并将其作为兜底值返回。
 *              默认值为 `window`（浏览器环境）或 `undefined`（SSR）。
 *              可传入 `null` 以强制遍历到 `<html>` 为止，也可传入任意 HTMLElement 来自定义边界。
 *
 * @returns     最近的可滚动祖先节点；如果遍历结束仍未找到，则返回 `root`。
 *              浏览器环境下通常返回某个 HTMLElement 或 `window`。
 */
export const getScrollParent = (
  el: Element,
  root: ScrollElement | null | undefined = defaultRoot,
): Window | Element | null | undefined => {
  let node = el

  while (node && node !== root && isElement(node)) {
    if (node === document.body) {
      return root
    }
    const { overflowY } = window.getComputedStyle(node)
    if (
      overflowStylePatterns.includes(overflowY)
      && node.scrollHeight > node.clientHeight
    ) {
      return node
    }
    node = node.parentNode as Element
  }

  return root
}
